package com.seanLab.tool.TagBat;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Deprecated
public class TopicBat {
    public List<String> topics;
    public HashMap<String, String> topicIndex;

    private void loadTopic(String topicPath) throws IOException {
        JsonParser jsonParser = new JsonParser();
//        topics = new ArrayList<>();
        topicIndex = new HashMap<>(1021360 * 2 , 1);

//        JsonReader reader = new JsonReader(new InputStreamReader(new FileInputStream(topicPath)));
//        reader.beginArray();
//        while (reader.hasNext()) {
//            JsonObject object = jsonParser.parse(reader).getAsJsonObject();
//            topicIndex.put(object.get("_id").getAsString(),
//                    object.get("topicDistribution").getAsJsonObject().get("values").getAsJsonArray());
////            topics.add(jsonParser.parse(reader).getAsJsonObject().get("topicDistribution").getAsJsonObject().get("values").getAsJsonArray());
//        }
//        reader.close();

        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(topicPath)));
        String line = null;
        int count = 0;
        while ((line = reader.readLine()) != null) {
            JsonObject object = jsonParser.parse(line).getAsJsonObject();
            topicIndex.put(object.get("_id").getAsString(),
                    line);
//                    object.get("topicDistribution").getAsJsonObject().get("values"));
//            topics.add(jsonParser.parse(line).getAsJsonObject().get("topicDistribution").getAsJsonObject().get("values").getAsJsonArray());
            if (++count % 5000 == 0) {
                System.out.println("read doc " + count);
            }
        }
        reader.close();
        System.out.println("Articles size: " + count);
        System.out.println("Index size: " + topicIndex.size());
    }

//    private void buildIndex() {
//        topicIndex = new HashMap<>(topics.size() * 3);
//        for (JsonObject topic : topics) {
//            String id = topic.get("_id").getAsString();
//            topicIndex.put(id, topic);
//        }
//        System.out.println("Index size: " + topicIndex.size());
//    }



    private void parallel(String[] paths, String idField, String targetField) {
        List<Thread> threads = new ArrayList<>();
        int threadNum = 0;
        for (String path : paths) {
            threads.add(new Thread(new TopicThread(threadNum++, path, idField, targetField)));
        }
        for (Thread thread : threads) {
            thread.start();
        }
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws IOException{
//        if (args.length == 0) {
//            TopicBat main = new TopicBat();
//            main.loadTopic("workingDir/topicDataset.json");
//            main.buildIndex();
//            main.parallel(new String[]{"workingDir/topicTestset.json"}, "_id", "articleTopic");
////        main.parseIndex("", "articleID", "imgTopic");
//        }
        String[] paths = new String[args.length - 3];
        System.arraycopy(args, 3, paths, 0, paths.length);
        TopicBat main = new TopicBat();
        main.loadTopic(args[2]);
//        main.buildIndex();
        main.parallel(paths, args[0], args[1]);
    }

    private class TopicThread implements Runnable {
        private int threadID;
        private String datasetPath;
        private String idField;
        private String targetField;

        public TopicThread(int threadID, String datasetPath, String idField, String targetField) {
            this.threadID = threadID;
            this.datasetPath = datasetPath;
            this.idField = idField;
            this.targetField = targetField;
        }

        private void parseIndex(String datasetPath, String idField, String targetField) throws IOException{
            JsonParser jsonParser = new JsonParser();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
                    datasetPath.substring(0, datasetPath.lastIndexOf(".")) + "_topics.json"
            )));
//            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(datasetPath)));
            JsonReader reader = new JsonReader(new InputStreamReader(new FileInputStream(datasetPath)));
            reader.beginArray();
            int count = 0;

            String line =null;
//            while ((line = reader.readLine()) != null) {
            while (reader.hasNext()) {
//                JsonObject jsonObject = jsonParser.parse(line).getAsJsonObject();
                JsonObject jsonObject = jsonParser.parse(reader).getAsJsonObject();
                String id = jsonObject.get(idField).getAsString();
                if (!topicIndex.containsKey(id)) {
                    System.out.println("index error: " + jsonObject.get("_id"));
                    continue;
                }
                jsonObject.add(targetField,
                        jsonParser.parse(topicIndex.get(id)).getAsJsonObject()
                                .get("topicDistribution").getAsJsonObject().get("values").getAsJsonArray());
                writer.write(jsonObject.toString());
                writer.newLine();
                if (++count % 1000 == 0) {
                    writer.flush();
                    System.out.println("thread-" + threadID + " parse docs :" + count);
                }
            }
            System.out.println("thread-" + threadID + " parse docs :" + count);
            writer.flush();
            writer.close();
            reader.close();
        }

        @Override
        public void run() {
            try {
                parseIndex(datasetPath, idField, targetField);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
